import { loggerRequest } from './log'
import { createOrder } from '@/api/home'

let showGoLoginPopup = false

/**
 * promise化
 * @param {*} functionName 属性名
 * @param {*} defaultOption 默认设置
 */
function promisify(functionName, defaultOption) {
  return function (option) {
    // console.log(option)
    return new Promise((resolve, reject) => {
      uni[functionName]({
        ...defaultOption,
        ...option,
        success: (res) => resolve(res),
        fail: (res) => reject(res)
      })
    })
  }
}

const uniProxy = new Proxy(uni, {
  get(target, prop) {
    switch (prop) {
      case 'request':
        return promisifyRequest
      case 'showToast':
        return promisify(prop, { icon: 'none', duration: 2000 })
      case 'showModal':
        return promisify(prop, { confirmColor: '#00A2FF' })
      case 'uploadFile':
        return promisify(prop, {
          header: {
            Authorization: `Bearer ${uni.getStorageSync('APP_TOKEN')}` || ''
          }
        })
      // app 中调起支付
      case 'appPayment':
        return function (data) {
          // eslint-disable-next-line no-async-promise-executor
          return new Promise(async (resolve, reject) => {
            try {
              const res = await createOrder(data)
              if (res.code === 200) {
                uni.requestPayment({
                  provider: 'weixin',
                  ...res.data,
                  success: (res) => resolve(res),
                  fail: (res) => reject(res)
                })
              } else {
                reject(res)
              }
            } catch (error) {
              reject(error)
              console.log(error)
            }
          })
        }
      default:
        return promisify(prop)
    }
  }
})

// 根据 { method, header, ...option } cache 返回status===200 的请求结果
const cacheMap = new Map()
// 串行, 显示Loading的请求数
let loadingRequestCount = 0
// 是否关闭loading
function whetherCloseLoading(showLoading) {
  if (showLoading) {
    loadingRequestCount--
    if (loadingRequestCount === 0) {
      uni.hideLoading()
    }
  }
}
/**
 * promisifyRequest
 * @param {*} option
 */
function promisifyRequest({ showLoading = true, method = 'GET', cache = false, header = {}, ...option }) {
  return new Promise((resolve, reject) => {
    const requestCacheKey = JSON.stringify({ method, header, ...option })

    if (cache && cacheMap.has(requestCacheKey)) {
      console.log('get cache', requestCacheKey, cacheMap.get(requestCacheKey))
      return resolve(cacheMap.get(requestCacheKey))
    }

    if (showLoading) {
      if (loadingRequestCount === 0) {
        uni.showLoading({
          title: '加载中',
          mask: true
        })
      }
      loadingRequestCount++
    }

    const token = uni.getStorageSync('APP_TOKEN')
    if (token) {
      header.Authorization = `Bearer ${token}`
    }
    uni.request({
      ...option,
      // content-type 默认为 application/json
      header: {
        ...header
        // Authorization: `Bearer ${uni.getStorageSync('APP_TOKEN')}` || ''
      },
      method: method,
      success: (res) => {
        whetherCloseLoading(showLoading)

        // 测试用
        if (process.env.URL_ENV_TEST === 'test' && process.env.NODE_ENV === 'production') {
          console.info({ method, header, ...option, res })
        }

        if (res.statusCode === 200) {
          // code === 500 提示
          if (res.data.code >= 500) {
            uni.showToast({
              title: res.data.msg,
              icon: 'none'
            })
          } else if (res.data.code === 401) {
            if (showGoLoginPopup) return
            showGoLoginPopup = true
            //
            return uni.showModal({
              content: '您还未登录请先登录',
              confirmColor: '#00A2FF',
              success(res) {
                showGoLoginPopup = false
                if (res.confirm) {
                  uni.navigateTo({
                    url: '/pages/login/index'
                  })
                } else if (res.cancel) {
                  // console.log('用户点击取消')
                }
              }
            })
          }

          // 缓存请求 MAYBE: 过期时间
          if (cache) {
            cacheMap.set(requestCacheKey, res.data)
          }
          // 全走try
          resolve(res.data)
        } else if (res.statusCode >= 500) {
          // log
          loggerRequest(option, res)

          uni.showToast({
            title: '服务端响应错误',
            icon: 'none'
          })
          reject(res)
        } else if (res.statusCode === 403) {
          // uni.showToast({
          //   title: '登录失效,请重启',
          //   icon: 'none'
          // })
          reject(res)
        } else {
          console.log('statusCode error', res)
          loggerRequest(option, res)
          uni.showToast({
            title: '服务端响应错误',
            icon: 'none'
          })
          reject(res)
        }
      },
      fail: (res) => {
        whetherCloseLoading(showLoading)
        console.log('request fail', res)
        loggerRequest(option, res)
        uni.showToast({
          title: '网络异常',
          icon: 'none'
        })
        reject(res)
      },
      complete: (res) => {
        // console.log('request', res)
        // wx.hideLoading()会关闭同级中的wx.showLoading 或 wx.showToast
        // 所以要在showToast之前调用wx.hideLoading
        // if (showLoading) {
        //   uni.hideLoading()
        // }
      }
    })
  })
}

export default uniProxy
